import os
import akshare as ak
import pandas as pd
import numpy as np
from utils import FileUtils

class BoardHeatScoreCalculator:
    def __init__(self):
        """初始化板块热力得分计算器"""
        # 权重配置
        self.weights = {
            '涨跌幅': 0.25,
            '成交量': 0.15,
            '成交额': 0.15,
            '净流入': 0.20,
            '上涨比例': 0.15,
            '领涨股': 0.10
        }
    
    def fetch_data(self):
        """获取板块数据"""
        return ak.stock_board_industry_summary_ths()
    
    def preprocess_data(self, df):
        """数据预处理"""
        # 处理涨跌幅
        if df['涨跌幅'].dtype == 'object':
            df['涨跌幅'] = df['涨跌幅'].str.replace('%', '').astype(float)
        elif pd.api.types.is_numeric_dtype(df['涨跌幅']):
            pass
        
        # 处理领涨股-涨跌幅
        if df['领涨股-涨跌幅'].dtype == 'object':
            df['领涨股-涨跌幅'] = df['领涨股-涨跌幅'].str.replace('%', '').astype(float)
        elif pd.api.types.is_numeric_dtype(df['领涨股-涨跌幅']):
            pass
        
        return df
    
    def calculate_normalized_scores(self, df):
        """计算各指标的归一化得分"""
        # 1. 涨跌幅归一化
        df['涨跌幅得分'] = (df['涨跌幅'] + 10) / 20
        df['涨跌幅得分'] = df['涨跌幅得分'].clip(0, 1)
        
        # 2. 成交量归一化
        df['成交量得分'] = df['总成交量'].rank(pct=True)
        
        # 3. 成交额归一化
        df['成交额得分'] = df['总成交额'].rank(pct=True)
        
        # 4. 净流入归一化
        max_inflow = df['净流入'].max()
        min_inflow = df['净流入'].min()
        range_inflow = max_inflow - min_inflow
        df['净流入得分'] = (df['净流入'] - min_inflow) / range_inflow if range_inflow != 0 else 0.5
        
        # 5. 上涨家数比例
        df['上涨比例'] = df['上涨家数'] / (df['上涨家数'] + df['下跌家数'])
        
        # 6. 领涨股表现
        df['领涨股得分'] = (df['领涨股-涨跌幅'] + 10) / 20
        df['领涨股得分'] = df['领涨股得分'].clip(0, 1)
        
        return df
    
    def calculate_heat_score(self, df):
        """计算热力得分"""
        df['热力得分'] = (
            df['涨跌幅得分'] * self.weights['涨跌幅'] +
            df['成交量得分'] * self.weights['成交量'] +
            df['成交额得分'] * self.weights['成交额'] +
            df['净流入得分'] * self.weights['净流入'] +
            df['上涨比例'] * self.weights['上涨比例'] +
            df['领涨股得分'] * self.weights['领涨股']
        ) * 100
        
        # 确保得分在0-100之间
        df['热力得分'] = df['热力得分'].clip(0, 100).round(2)
        
        return df
    
    def get_result(self, df):
        """获取最终结果"""
        return df[['板块', '涨跌幅', '总成交量', '总成交额', '净流入', 
                  '上涨家数', '下跌家数', '热力得分']].sort_values('热力得分', ascending=False)
    
    def run(self):
        """执行完整的计算流程"""
        df = self.fetch_data()
        df = self.preprocess_data(df)
        df = self.calculate_normalized_scores(df)
        df = self.calculate_heat_score(df)
        return self.get_result(df)

if __name__ == "__main__":
    # 计算热力得分
    calculator = BoardHeatScoreCalculator()
    heat_scores = calculator.run()
    
    # 保存到Python文件所在目录下的data文件夹
    current_dir = os.path.dirname(os.path.abspath(__file__))
    data_dir = os.path.join(current_dir, "data")
    file_path = FileUtils.save_to_excel(heat_scores, data_dir)
    
    print(f"板块热力得分已保存到: {file_path}")